/*
 * Copyright (c) 2023 Huawei Technologies Co., Ltd.
 * openUBMC is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *         http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

#include "interface/network_adapter.h"
#include <functional>

namespace dev {

bool NetworkAdapter::update_firmware_version_by_ncsi() {
    if (!m_ncsi_over_mctp_mellanox) {
        elog("Error: ncsi_over_mctp_mellanox not initialized");
        return false;
    }

    ncsi_version_id_info_t version_id = {};
    bool ret = m_ncsi_over_mctp_mellanox->get_version_id(m_package_id, DEFAULT_CHANNEL_ID,
                                                       &version_id);
    if (!ret) {
        dlog("Error: Failed to update version id");
        return false;
    }

    char buffer[16] = {0};
    snprintf(buffer, sizeof(buffer), "%02d.%02d.%04d", version_id.firmware_ver[0],
            version_id.firmware_ver[1], ((version_id.firmware_ver[2] << 8) | version_id.firmware_ver[3]));

    std::string firmware_version(buffer);
    
    FirmwareVersion.set_value(firmware_version);
    return true;
}

void NetworkAdapter::start_ncsi_update_task_mellanox(ncsi_over_mctp_mellanox_ptr ncsi_over_mctp,
                                                     mc::milliseconds      interval,
                                                     uint8_t package_id) {
    if (!ncsi_over_mctp) {
        elog("Error: ncsi_over_mctp_mellanox is null, skip start_ncsi_update_task_mellanox");
        return;
    }

    m_ncsi_timer              = new mc::core::timer(this);
    m_ncsi_over_mctp_mellanox = ncsi_over_mctp;
    m_package_id = package_id;
    m_ncsi_timer->timeout.connect([this]() {
        update_firmware_version_by_ncsi();
    });
    m_ncsi_timer->set_single_shot(false);
    m_ncsi_timer->start(interval);
}

void NetworkAdapter::stop_ncsi_update_task() {
    if (m_ncsi_timer) {
        m_ncsi_timer->stop();
    }
    if (m_ncsi_over_mctp_mellanox) {
        m_ncsi_over_mctp_mellanox = nullptr;
    }
}

void NetworkAdapter::register_os_reset_callback(const os_reset_callback& callback) {
    m_os_reset_callback = callback;
}

void NetworkAdapter::unregister_os_reset_callback() {
    m_os_reset_callback = nullptr;
}

void NetworkAdapter::HandleOsResetSignal() {
    if (m_os_reset_callback) {
        m_os_reset_callback();
    }
}


} // namespace dev

MC_REFLECT(dev::NetworkAdapter)